home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / GDIMETA.PAK / PENDLG.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  13KB  |  456 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   pendlg.c
  9. //
  10. //  PURPOSE:  Displays the "Pen Style" dialog box
  11. //
  12. //  FUNCTIONS:
  13. //    PenDlg          - Process messages for "Pen Style" dialog box.
  14. //    MsgPenInit      - Initialize the Pen dialog with info from lparam.
  15. //    MsgPenPaint     - Paint the Example Window in the Pen dialog
  16. //    MsgPenCommand   - Process WM_COMMAND messages sent to the Pen dialog.
  17. //    CmdPenStyle     - Track the currently selected pen style.
  18. //    CmdPenColor     - Put up the ChooseColor dialog to select pen color.
  19. //    CmdPenDone      - Free the Pen dialog and related data.
  20. //
  21. //  COMMENTS:
  22. //
  23.  
  24. #include <windows.h>            // required for all Windows applications
  25. #include <windowsx.h>
  26. #include <commctrl.h>
  27. #include "globals.h"            // prototypes specific to this application
  28. #include "pendlg.h"             // Controls ID's for the Pen dialog
  29. #include "colordlg.h"           // Palette choose color dialog
  30.  
  31. // global variables specific to this module
  32. RECT rcExample;                 // location of example window in dialog
  33.  
  34. // prototypes specific to this module
  35. LRESULT MsgPenInit    (HWND, UINT, WPARAM, LPARAM);
  36. LRESULT MsgPenPaint   (HWND, UINT, WPARAM, LPARAM);
  37. LRESULT MsgPenCommand (HWND, UINT, WPARAM, LPARAM);
  38. LRESULT CmdPenStyle   (HWND, WORD, WORD, HWND);
  39. LRESULT CmdPenColor   (HWND, WORD, WORD, HWND);
  40. LRESULT CmdPenDone    (HWND, WORD, WORD, HWND);
  41.  
  42. // Pen dialog message table definition.
  43. MSD rgmsdPen[] =
  44. {
  45.     {WM_COMMAND,    MsgPenCommand},
  46.     {WM_PAINT,      MsgPenPaint},
  47.     {WM_INITDIALOG, MsgPenInit}
  48. };
  49.  
  50. MSDI msdiPen =
  51. {
  52.     sizeof(rgmsdPen) / sizeof(MSD),
  53.     rgmsdPen,
  54.     edwpNone
  55. };
  56.  
  57. // Pen dialog command table definition.
  58. CMD rgcmdPen[] =
  59. {
  60.     {IDD_PENSTYLE,  CmdPenStyle},   // Pen Style notification msg
  61.     {IDD_PENCOLOR,  CmdPenColor},   // Color button
  62.     {IDOK,          CmdPenDone},    // OK and Cancel buttons
  63.     {IDCANCEL,      CmdPenDone}
  64. };
  65.  
  66. CMDI cmdiPen =
  67. {
  68.     sizeof(rgcmdPen) / sizeof(CMD),
  69.     rgcmdPen,
  70.     edwpNone
  71. };
  72.  
  73.  
  74. //
  75. //  FUNCTION: PenDlg(HWND, UINT, WPARAM, LPARAM)
  76. //
  77. //  PURPOSE:  Processes messages for "Pen Style" dialog box.
  78. //
  79. //  PARAMETERS:
  80. //    hdlg - window handle of the dialog box
  81. //    wMessage - type of message
  82. //    wparam - message-specific information
  83. //    lparam - message-specific information
  84. //
  85. //  RETURN VALUE:
  86. //    TRUE - message handled
  87. //    FALSE - message not handled
  88. //
  89. //  COMMENTS:
  90. //
  91. //
  92.  
  93. LRESULT CALLBACK PenDlg(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  94. {
  95.     return DispMessage(&msdiPen, hdlg, uMessage, wparam, lparam);
  96. }
  97.  
  98.  
  99. //
  100. //  FUNCTION: MsgPenInit(HWND, UINT, WPARAM, LPARAM)
  101. //
  102. //  PURPOSE: To initialize the Pen dialog with info from lparam.
  103. //
  104. //  PARAMETERS:
  105. //    hwnd - The window handing the message.
  106. //    uMessage - The message number. (unused).
  107. //    wparam - Message specific data (unused).
  108. //    lparam - points to LOGPEN structure.
  109. //
  110. //  RETURN VALUE:
  111. //    Always returns TRUE
  112. //
  113. //  COMMENTS:
  114. //    Sets the initial state of the controls according to the LOGPEN
  115. //      passed in via lparam.
  116. //
  117.  
  118. #pragma argsused
  119. LRESULT MsgPenInit(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  120. {
  121.     int i, nIndex, nSel;
  122.     HWND hctlStyle;
  123.     char szTmp[32];
  124.     LPLOGPEN lpLP;
  125.  
  126.     // lparam is a pointer to a LOGPEN structure
  127.     lpLP = (LPLOGPEN)lparam;
  128.  
  129.     // Save pointer to LOGPEN structure in window bytes
  130.     SetWindowLong(hdlg, DWL_USER, (LONG)lpLP);
  131.  
  132.     // Center the dialog over the application window
  133.     CenterWindow(hdlg, GetWindow(hdlg, GW_OWNER));
  134.  
  135.     // Fill up the style combobox.  The item data is set to the
  136.     // corresponding pen style defined in windows.h (e.g. PS_SOLID).
  137.  
  138.     hctlStyle = GetDlgItem(hdlg, IDD_PENSTYLE);
  139.     nSel = 0;
  140.  
  141.     for (i = IDD_PENFIRST; i <= IDD_PENLAST; i++)
  142.     {
  143.         LoadString(hInst, i, szTmp, sizeof(szTmp));
  144.         nIndex = SendMessage(hctlStyle, CB_ADDSTRING, 0, (LPARAM)(LPSTR)szTmp);
  145.         SendMessage(hctlStyle, CB_SETITEMDATA, nIndex, i - IDD_PENSTYLE);
  146.  
  147.         // If this item is the current style, remember it
  148.         if (i == IDD_PENSTYLE + (int)lpLP->lopnStyle)
  149.             nSel = nIndex;
  150.     }
  151.  
  152.     // Set the initial style selection
  153.     SendMessage(hctlStyle, CB_SETCURSEL, nSel, 0L);
  154.  
  155.     // Initialize the Width edit control
  156.     SetDlgItemInt(hdlg, IDD_PENWIDTH, lpLP->lopnWidth.x, FALSE);
  157.  
  158.     // Example window always uses 0 width (so styles work)
  159.     lpLP->lopnWidth.x = 0;
  160.  
  161.     // Get coordinates of the example window in the dialog
  162.     GetWindowRect(GetDlgItem(hdlg, IDD_PENEXAMPLE), &rcExample);
  163.     ScreenToClient(hdlg, (LPPOINT)&rcExample);
  164.     ScreenToClient(hdlg, ((LPPOINT)&rcExample) + 1);
  165.  
  166.     // Reduce rect slightly so we don't paint over its frame
  167.     InflateRect(&rcExample, -1, -1);
  168.  
  169.     return TRUE;
  170. }
  171.  
  172.  
  173. //
  174. //  FUNCTION: MsgPenPaint(HWND, UINT, WPARAM, LPARAM)
  175. //
  176. //  PURPOSE: Paint the example window with examples of the current pen
  177. //
  178. //  PARAMETERS:
  179. //    hwnd - The window handling the message.
  180. //    uMessage - The message number. (unused).
  181. //    wparam - Message specific data (unused).
  182. //    lparam - Message specific data (unused).
  183. //
  184. //  RETURN VALUE:
  185. //    Always returns TRUE
  186. //
  187. //  COMMENTS:
  188. //    Sets the initial state of the controls according to the LOGPEN
  189. //    passed in via lparam.
  190. //
  191.  
  192. #pragma argsused
  193. LRESULT MsgPenPaint(HWND hdlg, UINT uMessage, WPARAM wparam, LPARAM lparam)
  194. {
  195.     PAINTSTRUCT ps;
  196.     HPEN hpen, hpenBlack;
  197.     LPLOGPEN lpLP;
  198.     int i, y, dy;
  199.  
  200.     BeginPaint(hdlg, &ps);
  201.  
  202.     // select our logical palette for palette-relative colors to work
  203.     if (hPalette)
  204.         SelectPalette(ps.hdc, hPalette, TRUE);
  205.  
  206.      SetBkMode(ps.hdc, TRANSPARENT);
  207.     SelectObject(ps.hdc, GetStockObject(NULL_BRUSH));
  208.  
  209.     // Get pointer to LOGPEN from window bytes
  210.     lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  211.  
  212.  
  213.     // Draw some stuff in the example window with pens based on
  214.     // the current LOGPEN (vary the width starting at 0).
  215.  
  216.     #define NUMLINES    5
  217.  
  218.      y = rcExample.top;
  219.     dy = (rcExample.bottom - rcExample.top) / (NUMLINES + 1);
  220.     lpLP->lopnWidth.x = 0;
  221.     hpenBlack = GetStockObject(BLACK_PEN);
  222.  
  223.     for (i = 0; i < NUMLINES; i++)
  224.     {
  225.         lpLP->lopnWidth.x = i*3;
  226.         hpen = CreatePenIndirect(lpLP);
  227.         SelectObject(ps.hdc, hpen);
  228.  
  229.         MoveToEx(ps.hdc, rcExample.left + 10, y += dy, NULL);
  230.           LineTo(ps.hdc, rcExample.right - 10, y);
  231.  
  232.         // Deselect and delete the pen
  233.         SelectObject(ps.hdc, hpenBlack);
  234.         DeleteObject(hpen);
  235.     }
  236.  
  237.     // de-select our logical palette from the DC
  238.     if (hPalette)
  239.         SelectPalette(ps.hdc, GetStockObject(DEFAULT_PALETTE), TRUE);
  240.  
  241.     EndPaint(hdlg, &ps);
  242.      return 0;
  243. }
  244.  
  245.  
  246. //
  247. //  FUNCTION: MsgPenCommand(HWND, UINT, WPARAM, LPARAM)
  248. //
  249. //  PURPOSE: Process WM_COMMAND messages sent to the PenStyle box.
  250. //
  251. //  PARAMETERS:
  252. //    hwnd      - The window handing the message.
  253. //    uMessage  - The message number. (unused).
  254. //    wparam    - Message specific data (unused).
  255. //    lparam    - Message specific data (unused).
  256. //
  257. //  RETURN VALUE:
  258. //    Always returns 0 - message handled.
  259. //
  260. //  COMMENTS:
  261. //    Uses this DipsCommand function defined in wndproc.c combined
  262. //    with the cmdiPen structure defined in this file to handle
  263. //    the command messages for the Pen dialog box.
  264. //
  265.  
  266. #pragma argsused
  267. LRESULT MsgPenCommand(HWND   hwnd,
  268.                              UINT   uMessage,
  269.                              WPARAM wparam,
  270.                              LPARAM lparam)
  271. {
  272.     return DispCommand(&cmdiPen, hwnd, wparam, lparam);
  273. }
  274.  
  275.  
  276. //
  277. //  FUNCTION: CmdPenStyle(HWND, WORD, WORD, HWND)
  278. //
  279. //  PURPOSE: Keeps track of which style button is selected.
  280. //
  281. //  PARAMETERS:
  282. //    hwnd      - The window handling the command.
  283. //    wCommand  - Child control ID (unused).
  284. //    wNotify   - Child notification code.
  285. //    hwndCtrl  - NULL (unused).
  286. //
  287. //  RETURN VALUE:
  288. //    Always returns TRUE.
  289. //
  290. //  COMMENTS:
  291. //
  292.  
  293. #pragma argsused
  294. LRESULT CmdPenStyle(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  295. {
  296.     LPLOGPEN lpLP;
  297.     int nSel;
  298.  
  299.     // Get pointer to LOGPEN from window bytes
  300.     lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  301.  
  302.      // Update the style selection if necessary.
  303.     if (CBN_SELCHANGE == wNotify)
  304.     {
  305.         nSel = SendMessage(hwndCtrl, CB_GETCURSEL, 0, 0L);
  306.         if (CB_ERR != nSel)
  307.         {
  308.             // Save new style
  309.             lpLP->lopnStyle = SendMessage(hwndCtrl, CB_GETITEMDATA, nSel, 0L);
  310.  
  311.             // Repaint the example window
  312.             InvalidateRect(hdlg, &rcExample, TRUE);
  313.         }
  314.      }
  315.  
  316.     return TRUE;
  317. }
  318.  
  319.  
  320. //
  321. //  FUNCTION: CmdPenColor(HWND, WORD, WORD, HWND)
  322. //
  323. //  PURPOSE: Puts up ChooseColor dialog to choose pen color.
  324. //
  325. //  PARAMETERS:
  326. //    hwnd      - The window handling the command.
  327. //    wCommand  - IDD_PENCOLOR (unused).
  328. //    wNotify   - Child notification code (unused).
  329. //    hwndCtrl  - NULL (unused).
  330. //
  331. //  RETURN VALUE:
  332. //    Always returns TRUE.
  333. //
  334. //  COMMENTS:
  335. //
  336.  
  337. #pragma argsused
  338. LRESULT CmdPenColor(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  339. {
  340.     LPLOGPEN   lpLP;
  341.     static int nPalIndex=0; // stores system palette index for init'ing
  342.                             // the palette color selection dialog
  343.  
  344.     // Get pointer to LOGPEN from window bytes
  345.     lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  346.  
  347.     if (bPalDevice)
  348.     {
  349.         // call palette dialog, passing nPalIndex as LPARAM to initialize
  350.           // the correct selection in the dialog
  351.         DialogBoxParam(hInst, "ColorDlg", hdlg, (DLGPROC)Color, (LPARAM)nPalIndex);
  352.  
  353.         if (palinfo.index != -1)
  354.         {
  355.             // save index of color selection
  356.             nPalIndex = palinfo.index;
  357.  
  358.             if (palinfo.index >= 10 && palinfo.index <= 245)
  359.             {
  360.                 // Non-static color was chosen, so use PALETTERGB macro
  361.                 // to save new color
  362.                      lpLP->lopnColor = PALETTERGB(palinfo.red, palinfo.green, palinfo.blue);
  363.             }
  364.             else
  365.             {
  366.                 // Static color was chosen, so just use RGB macro
  367.                 // to save new color
  368.                 lpLP->lopnColor = RGB(palinfo.red, palinfo.green, palinfo.blue);
  369.             }
  370.         
  371.             // Repaint the example window
  372.             InvalidateRect(hdlg, &rcExample, TRUE);        
  373.         }
  374.      }
  375.     else // not a palette device, so just use ChooseColor Common Dialog
  376.     {
  377.         CHOOSECOLOR cc;
  378.         static DWORD dwCustColors[16];
  379.  
  380.         // Initialize CHOOSECOLOR struct
  381.         cc.lStructSize      = sizeof(cc);
  382.         cc.hwndOwner        = hdlg;
  383.         cc.hInstance        = NULL;
  384.         cc.rgbResult        = lpLP->lopnColor;
  385.         cc.lpCustColors     = dwCustColors;
  386.           cc.Flags            = CC_RGBINIT;
  387.         cc.lCustData        = 0;
  388.         cc.lpfnHook         = NULL;
  389.         cc.lpTemplateName   = NULL;
  390.  
  391.         if (ChooseColor(&cc))
  392.         {
  393.             // Save new color
  394.             lpLP->lopnColor = cc.rgbResult;
  395.  
  396.             // Repaint the example window
  397.             InvalidateRect(hdlg, &rcExample, TRUE);
  398.           }
  399.     }
  400.  
  401.     return TRUE;
  402. }
  403.  
  404.  
  405. //
  406. //  FUNCTION: CmdPenDone(HWND, WORD, WORD, HWND)
  407. //
  408. //  PURPOSE: Free the PenStyle box and related data.
  409. //
  410. //  PARAMETERS:
  411. //    hwnd      - The window handling the command.
  412. //    wCommand  - The command to be handled.
  413. //    wNotify   - Notification code (unused).
  414. //    hwndCtrl  - NULL (unused).
  415. //
  416. //  RETURN VALUE:
  417. //    Always returns TRUE.
  418. //
  419. //  COMMENTS:
  420. //    Calls EndDialog to finish the dialog session.
  421. //
  422.  
  423. #pragma argsused
  424. LRESULT CmdPenDone(HWND hdlg, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  425. {
  426.      LPLOGPEN lpLP;
  427.     UINT nWidth;
  428.     BOOL bTranslated;
  429.  
  430.     if (IDOK == wCommand)
  431.     {
  432.         // Get pointer to LOGPEN from window bytes
  433.         lpLP = (LPLOGPEN)GetWindowLong(hdlg, DWL_USER);
  434.  
  435.         // Get pen width from edit control
  436.         nWidth = GetDlgItemInt(hdlg, IDD_PENWIDTH, &bTranslated, FALSE);
  437.  
  438.           if (bTranslated)                // Did GetDlgItemInt succeed?
  439.         {
  440.             lpLP->lopnWidth.x = nWidth; // Yes, save new width.
  441.             EndDialog(hdlg, TRUE);      // Exit the dialog (success)
  442.         }
  443.         else                            // Error
  444.         {
  445.             MessageBox(hdlg, "Pen Width must be a non-negative integer.",
  446.                         "Pen Style", MB_ICONINFORMATION | MB_OK);
  447.             SetDlgItemInt(hdlg, IDD_PENWIDTH, lpLP->lopnWidth.x, FALSE);
  448.             SetFocus(GetDlgItem(hdlg, IDD_PENWIDTH));
  449.         }
  450.      }
  451.     else    // Just close the dialog (cancel)
  452.         EndDialog(hdlg, FALSE);
  453.  
  454.     return TRUE;
  455. }
  456.